package club.mzywucai.blog.file_system.upload;

import club.mzywucai.blog.file_system.exception.FileTypeErrorException;
import club.mzywucai.blog.file_system.pojo.domain.JsonData;
import club.mzywucai.blog.file_system.pojo.domain.MakeDir;
import club.mzywucai.blog.file_system.pojo.domain.UploadResult;
import club.mzywucai.blog.file_system.pojo.vo.UserVo;
import club.mzywucai.blog.file_system.service.RelatedUploadService;
import club.mzywucai.blog.file_system.util.SizeToStringUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.UUID;

/**
 * @author mzywucai
 * @Description
 * @date 2019/2/7
 */
@Data
@PropertySource({"classpath:config/application.properties"})
@WebServlet("/api/user/upload_photo")
public class PhotoUpload extends HttpServlet {
    /**
     * @Description 缓存中间目录的位置
     */
    @Value("${server.file.tmp}")
    private String tmpPath;
    /**
     * @Description 最大的文件大小：单位B
     */
    @Value("${photo.max-size}")
    private Long maxSize;

    @Value("${server.photo.uri}")
    private String photoURI;

    @Autowired
    MakeDir mkdir;

    @Autowired
    RelatedUploadService relatedUploadService;

    boolean firstCome = true;

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        ObjectMapper mapper = new ObjectMapper();
        PrintWriter writer = response.getWriter();
        String json; //  = mapper.writeValueAsString(user);

        // springboot 通用的拦截器对原生servlet无效，故手动拦截
        HttpSession session = request.getSession();
        UserVo user = (UserVo) session.getAttribute("user");
        if (null == user) {
            json = mapper.writeValueAsString(JsonData.buildError("请先登录再进行操作"));
            writer.write(json);
            writer.flush();

            return;
        }



        if (firstCome) {
            try {
                mkdir.mkdir();
                System.out.println("first come");
            } catch (Exception e) {
                System.out.println("进入异常？");

                json = mapper.writeValueAsString(JsonData.buildError("文件服务器初始化创建文件夹失败！"));
                writer.write(json);
                // return JsonData.buildError("文件服务器初始化创建文件夹失败！");
            }
        }
        firstCome = false;

        String uri = request.getRequestURI();
        String url = request.getRequestURL().toString();
        String host = url.replace(uri, "/");

        String originName = "";
        String newName = "";
        String suffix = "";
        String photoUrl = "";
        String photoUri = "";
        try {
            File tmp = new File(tmpPath);
            if (!tmp.exists()) {
                tmp.mkdirs();
            }
            DiskFileItemFactory factory = new DiskFileItemFactory(1024, tmp);
            ServletFileUpload upload = new ServletFileUpload(factory);
            // upload.setHeaderEncoding("utf-8");
            // 总
            upload.setSizeMax(maxSize);
            // 单个文件的最大容量为100KB
            upload.setFileSizeMax(maxSize);
            // 解析request
            List<FileItem> list = upload.parseRequest(request);
            if(list != null) {
                for(FileItem item: list) {
                    if(item.isFormField()) {
                        // 无普通字段
                    } else {
                        /*
                         * 注意：
                         * 		限制文件的类型。文件的
                         * 类型(mime-type)：image/*
                         * 只能上传图片
                         */
                        // 得到文件的类型
                        String contentType = item.getContentType();
                        if(!contentType.contains("image/")) {
                            throw new FileTypeErrorException("文件类型错误，请换一张图片！");
                        }
                        /*
                         * 使用UUID算法，生成唯一的文件名
                         * 避免文件覆盖的问题！
                         */
                        String uuid = UUID.randomUUID().toString();
                        // get到真正的文件名！
                        /*
                         * 这里我们就不用做兼容性的处理了
                         * 因我们只用get一个LastIndexOf(".")
                         * 去获得文件的后缀名，保证文件能够正常的打开！
                         */
                        originName = item.getName();
                        // 获取到后缀名
                        suffix = originName.substring(originName.lastIndexOf("."));
                        // 组合新的文件名
                        newName = uuid + suffix;


                        String path = mkdir.getPhotoPath();
                        // 位置：URI+文件名
                        photoUrl = host;

                        photoUrl = photoUrl + photoURI +"/"+ newName;
                        // photo/xxx.jpg  -->  /photo/xxx.jpg
                        photoUri = "/" + photoURI +"/"+ newName;
                        path = path +"/"+ newName;

                        File file = new File(path);
                        FileUtils.copyInputStreamToFile(item.getInputStream(), file);

                        // 删除item传输的tmp临时文件
                        item.delete();
                    }
                }
            }
        } catch (FileTypeErrorException e) {
            // 捕获文件类型异常
            json = mapper.writeValueAsString(JsonData.buildError("文件类型错误，请换一张图片！"));
            writer.write(json);
            // return JsonData.buildError("您上传的文件类型未知");
            return;
        } catch (FileUploadBase.FileSizeLimitExceededException e) {
            // 捕获单个文件大小超规定范围异常
            json = mapper.writeValueAsString(JsonData.buildError("您上传的图片大小超过规定："+ SizeToStringUtil.getSizeString(maxSize)));
            writer.write(json);
            // return JsonData.buildError("您上传的文件大小超过规定："+ SizeToStringUtil.getSizeString(maxSize));
            return;
        } catch (FileUploadBase.SizeLimitExceededException e) {
            // 捕获总文件大小超规定范围异常
            json = mapper.writeValueAsString(JsonData.buildError("您上传的图片大小超过规定："+ SizeToStringUtil.getSizeString(maxSize)));
            writer.write(json);
            // return JsonData.buildError("您上传的文件大小超过规定："+ SizeToStringUtil.getSizeString(maxSize));
            return;
        } catch (Exception e) {
            json = mapper.writeValueAsString(JsonData.buildError("系统异常"));
            writer.write(json);
            // return JsonData.buildError("系统异常");
            return;
        }
        UploadResult uploadResult = new UploadResult();
        // origin
        uploadResult.setOriginName(originName);
        // new
        uploadResult.setNewName(newName);
        // suffix
        uploadResult.setSuffix(suffix);
        // photoUrl
        uploadResult.setUrl(photoUrl);
        // photoUri
        uploadResult.setUri(photoUri);

        // HttpSession session = request.getSession();
        // UserVo userVo = (UserVo) session.getAttribute("user");
        // System.err.println(userVo);

        // 修改数据库中的地址
        relatedUploadService.updateUserPhotoURIByEmail(user, uploadResult);

        json = mapper.writeValueAsString(JsonData.buildSuccess(0, uploadResult, "上传成功"));
        writer.write(json);
        // return JsonData.buildSuccess(0, uploadResult, "操作成功");


        writer.flush();
    }
}
